package com.daffodil.core.dao.impl;

import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.persistence.EntityManager;
import javax.persistence.Query;

import org.hibernate.query.internal.NativeQueryImpl;
import org.hibernate.transform.Transformers;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import com.daffodil.core.dao.JdbcDao;
import com.daffodil.core.dao.helper.DaoHelper;
import com.daffodil.core.entity.Page;
import com.daffodil.core.exception.BusinessException;

/**
 * 
 * @author yweijian
 * @date 2022年3月3日
 * @version 1.0
 * @description
 */
@Repository("jdbcDao")
public class JdbcDaoImpl implements JdbcDao {
	
	@Autowired
	private EntityManager entityManager;

	private static int DEFAULT_PAGE_NUM  = 1;

	private static int DEFAULT_PAGE_SIZE  = 9999;

	public void execute(String sql) throws BusinessException {
		try {
			Query query = entityManager.createNativeQuery(sql);
			query.executeUpdate();
		} catch (Exception e) {
			throw new BusinessException("[JDBC] 执行SQL语句错误 ...", e);
		} 
	}

	public void execute(String sql, List<Object> paras) throws BusinessException {
		try {
			String querySql = DaoHelper.getQuerySql(sql);
			Query query = entityManager.createNativeQuery(querySql);
			DaoHelper.setQueryParas(query, paras);
			query.executeUpdate();
		} catch (Exception e) {
			throw new BusinessException("[JDBC] 执行SQL语句错误 ...", e);
		} 
	}

	@SuppressWarnings({ "unchecked"})
	public List<Map<String, String>> search(String sql) throws BusinessException {
		List<Map<String, String>> returnList = new LinkedList<>();
		try {
			Query query = entityManager.createNativeQuery(sql).unwrap(NativeQueryImpl.class).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
			List<Map<String, Object>> list = query.getResultList();
			for (Map<String, Object> map : list ) {
				Map<String, String> returnMap = new HashMap<String, String>();
				Set<String> key = map.keySet();
				for (Iterator<String> it = key.iterator(); it.hasNext(); ) {
					String s = it.next();
					returnMap.put(s.toLowerCase(), DaoHelper.objectDataToString(map.get(s)));
				} 
				returnList.add(returnMap);
			} 
		} catch (Exception e) {
			throw new BusinessException("[JDBC] 查询数据错误 ...", e);
		} 
		return returnList;
	}


	@SuppressWarnings({ "unchecked" })
	public List<Map<String, String>> search(String sql, Page page) throws BusinessException {
		if(null == page){
			page = new Page();
			page.setPageNumber(DEFAULT_PAGE_NUM);
			page.setPageSize(DEFAULT_PAGE_SIZE);
		}
		page.setTotalRow(this.count(DaoHelper.getQueryCountSql(sql)));
		List<Map<String, String>> returnList = new LinkedList<>();
		try {
			Query query = entityManager.createNativeQuery(sql).setFirstResult(page.getFromIndex()).setMaxResults(page.getPageSize())
					.unwrap(NativeQueryImpl.class).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
			List<Map<String, Object>> list = query.getResultList();
			for (Map<String, Object> map : list) {
				Map<String, String> returnMap = new HashMap<String, String>();
				Set<String> key = map.keySet();
				for (Iterator<String> it = key.iterator(); it.hasNext(); ) {
					String s = it.next();
					returnMap.put(s.toLowerCase(), DaoHelper.objectDataToString(map.get(s)));
				} 
				returnList.add(returnMap);
			} 
		} catch (Exception e) {
			throw new BusinessException("[JDBC] 分页查询数据错误 ...", e);
		} 
		return returnList;
	}



	@SuppressWarnings({ "unchecked" })
	public List<Map<String, String>> search(String sql, List<Object> paras) throws BusinessException {
		List<Map<String, String>> returnList = new LinkedList<>();
		try {
			String querySql = DaoHelper.getQuerySql(sql);
			Query query = entityManager.createNativeQuery(querySql).unwrap(NativeQueryImpl.class).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
			DaoHelper.setQueryParas(query, paras);
			List<Map<String, Object>> list = query.getResultList();
			for (Map<String, Object> map : list) {
				Map<String, String> returnMap = new HashMap<String, String>();
				Set<String> key = map.keySet();
				for (Iterator<String> it = key.iterator(); it.hasNext(); ) {
					String s = it.next();
					returnMap.put(s.toLowerCase(), DaoHelper.objectDataToString(map.get(s)));
				} 
				returnList.add(returnMap);
			} 
		} catch (Exception e) {
			throw new BusinessException("[JDBC] 查询数据错误 ...", e);
		} 
		return returnList;
	}

	@SuppressWarnings({ "unchecked" })
	public List<Map<String, String>> search(String sql, List<Object> paras, Page page) throws BusinessException {
		if(null == page){
			page = new Page();
			page.setPageNumber(DEFAULT_PAGE_NUM);
			page.setPageSize(DEFAULT_PAGE_SIZE);
		}
		page.setTotalRow(this.count(DaoHelper.getQueryCountSql(sql), paras));
		List<Map<String, String>> returnList = new LinkedList<>();
		try {
			String querySql = DaoHelper.getQuerySql(sql);
			Query query = entityManager.createNativeQuery(querySql).setFirstResult(page.getFromIndex()).setMaxResults(page.getPageSize())
					.unwrap(NativeQueryImpl.class).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
			DaoHelper.setQueryParas(query, paras);
			List<Map<String, Object>> list = query.getResultList();
			for (Map<String, Object> map : list) {
				Map<String, String> returnMap = new HashMap<>();
				Set<String> key = map.keySet();
				for (Iterator<String> it = key.iterator(); it.hasNext(); ) {
					String s = it.next();
					returnMap.put(s.toLowerCase(), DaoHelper.objectDataToString(map.get(s)));
				} 
				returnList.add(returnMap);
			} 
		} catch (Exception e) {
			throw new BusinessException("[JDBC] 分页查询数据错误 ...", e);
		} 
		return returnList;
	}

	public Map<String, String> find(String sql) throws BusinessException {
		return find(sql, null);
	}

	@SuppressWarnings({ "unchecked" })
	public Map<String, String> find(String sql, List<Object> paras) throws BusinessException {
		Map<String, String> resultMap = new HashMap<String, String>();
		try {
			String querySql = DaoHelper.getQuerySql(sql);
			Query query = entityManager.createNativeQuery(querySql).unwrap(NativeQueryImpl.class).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
			DaoHelper.setQueryParas(query, paras);
			List<Map<String, Object>> list = query.getResultList();
			for (Map<String, Object> map : list) {
				Set<String> key = map.keySet();
				for (Iterator<String> it = key.iterator(); it.hasNext(); ) {
					String s = it.next();
					resultMap.put(s.toLowerCase(), DaoHelper.objectDataToString(map.get(s)));
				} 
			} 
		} catch (Exception e) {
			throw new BusinessException("[JDBC] 查询数据错误 ...", e);
		} 
		return resultMap;
	}

	@SuppressWarnings({ "unchecked" })
	public Map<String, String> find(String sql, Object para) throws BusinessException {
		Map<String, String> resultMap = new HashMap<String, String>();
		try {
			String querySql = DaoHelper.getQuerySql(sql);
			Query query = entityManager.createNativeQuery(querySql).unwrap(NativeQueryImpl.class).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
			query.setParameter(0, para);
			List<Map<String, Object>> list = query.getResultList();
			for (Map<String, Object> map : list) {
				Set<String> key = map.keySet();
				for (Iterator<String> it = key.iterator(); it.hasNext(); ) {
					String s = it.next();
					resultMap.put(s.toLowerCase(), DaoHelper.objectDataToString(map.get(s)));
				} 
			} 
		} catch (Exception e) {
			throw new BusinessException("[JDBC] 查询数据错误 ...", e);
		} 
		return resultMap;
	}

	public int count(String sql) throws BusinessException {
		return count(sql, null);
	}
	
	@SuppressWarnings({ "unchecked" })
	public int count(String sql, List<Object> paras) throws BusinessException {
		int result = 0;
		try {
			String querySql = DaoHelper.getQuerySql(sql);
			Query query = entityManager.createNativeQuery(querySql).unwrap(NativeQueryImpl.class).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
			DaoHelper.setQueryParas(query, paras);
			List<Map<String, Object>> list = query.getResultList();
			for (Map<String, Object> map : list) {
				Set<String> key = map.keySet();
				for (Iterator<String> it = key.iterator(); it.hasNext(); ) {
					String s = it.next();
					result = Integer.parseInt(DaoHelper.objectDataToString(map.get(s)));
				} 
			} 
		} catch (Exception e) {
			throw new BusinessException("[JDBC] 查询数据错误 ...", e);
		} 
		return result;
	}
	
}
